#ifndef __SCRIPT_H__
#define __SCRIPT_H__

#include "script_var.h"
#include "script_expression.h"
#include "TFly_list.h"
#include "script_stack.h"
#include "script_memory.h"
#include "script_block.h"

#define SCRIPT_ERR_NONE				0
#define SCRIPT_ERR_PARAM			-1
#define SCRIPT_ERR_OPENFILE			-2
#define SCRIPT_ERR_MEMORY			-10
#define SCRIPT_ERR_SYNTAX			-100
#define SCRIPT_ERR_BRACE_UNPAIRED	-101
#define SCRIPT_ERR_VAR_DEFINE		-101
#define SCRIPT_ERR_CALC				-200

#define CHECK_RESULT(res) if(res == NULL || res->type == EXP_NODE_TYPE_ERR) return res


typedef struct script_t{
	char		*name;
	char		*code;					// 脚本的代码文本
	int			code_len;				// 代码长度
	int			code_buf_len;			// 代码buffer长度
	int			line;					// 当前解析行号

	TFly_list_t		*funcs;				// exp_func_t list

	TFly_list_t *includes;				// script_t list

	script_code_block_t *main_code;
	script_exec_block_t *exec_block;

	script_stack_t *code_stack;

}script_t;


script_t *script_script_create(void);

void script_destroy(script_t *script);

/********************************************************
 *	function	script_load
 *		从文件中加载脚本
 *
 * ******************************************************/
script_t *script_load(char *file);

/********************************************************
 *	function	script_add_global_var
 *		在script中添加一个全局变量
 *	
 *	@script		脚本指针
 *	@var_name	变量名称
 *	@value		变量值 可以传NULL
 *
 *	return
 *		成功返回SCRIPT_ERR_NONE
 * ******************************************************/
int script_add_global_var(script_t *script, char *var_name,char *value);

/********************************************************
 *	function	script_change_var_value
 *		修改脚本变量的值
 *
 * ******************************************************/
int script_change_var_value(script_t *script, char *var_name,char *value);

/********************************************************
 *	function	script_bind_c_var
 *		创建一个脚本变量绑定C变量
 *
 * ******************************************************/
int script_bind_c_var(script_t *script, char *var_name, script_var_type_e type, void *value);

/********************************************************
 *	function	script_run_code
 *		执行脚本语句销毁
 *	@script		脚本句柄
 *	@code		被执行代码
 *
 *	return		返回执行结果, 此结果需手动销毁
 *
 * ******************************************************/
exp_node_t *script_run_code(script_t *script, char *code);

/********************************************************
 *	function	script_run_code_easy
 *		执行脚本语句销毁
 *	@script		脚本句柄
 *	@code		被执行代码
 *
 *	return		成功返回0， 出错返回-1
 *
 * ******************************************************/
int script_run_code_easy(script_t *script, char *code);

/********************************************************
 *	function	run_block
 *		执行代码块
 *
 *	@block			代码块指针
 *	@block_stack	执行环境栈
 *	@var			传入代码块的执行局部变量， 可以为NULL
 *
 *	return			返回代码块执行结果,此结果需手动销毁
 *
 * ******************************************************/
exp_node_t *run_block(script_code_block_t *block, script_stack_t *block_stack,exp_var_t *var);
exp_node_t *_run_block(script_exec_block_t *e_block, script_stack_t *block_stack);

/********************************************************
 *	function	run_script
 *		运行脚本
 *
 * ******************************************************/
void run_script(script_t *script);

/********************************************************
 *	function	show_script
 *		查看脚本信息
 *
 * ******************************************************/
void show_script(script_t *script);

/********************************************************
 *	function	show_block
 *		查看代码块信息
 *
 * ******************************************************/
void show_block(script_code_block_t *block, int deep);

/********************************************************
 *
 * ******************************************************/
exp_var_t *script_var_find(script_stack_t *block_stack, char *var_name);

/********************************************************
 *	function	script_code_block_create
 *		创建代码块
 *
 * ******************************************************/
script_code_block_t *script_code_block_create(script_t *script);

/********************************************************
 *	function	script_code_block_destroy
 *		销毁代码块
 *
 * ******************************************************/
void script_code_block_destroy(script_code_block_t *block);

/********************************************************
 *	function	script_parse_from_string
 *		从字符串解析脚本
 *
 * ******************************************************/
int script_parse_from_string(script_t *script, char *str);

/********************************************************
 *	function	script_parse_from_file
 *		从文件解析脚本
 *
 * ******************************************************/
int script_parse_from_file(script_t *script, const char *file);

/********************************************************
 *	function	script_func_arg_get
 *		获取函数参数列表
 *
 * ******************************************************/
int script_func_arg_get(TFly_list_t *args,script_stack_t *block_stack, int argc, exp_node_t **arg);

/********************************************************
 *	function	script_func_arg_release
 *		释放函数参数列表
 *
 * ******************************************************/
void  script_func_arg_release(int argc, exp_node_t **arg);

/********************************************************
 *	function	script_name_set
 *		设置脚本名称
 *
 * ******************************************************/
int script_name_set(script_t *script, const char *name);
#endif

